1. Technical Field
The present application relates generally to an improved data processing system. More specifically, the present application is directed to an apparatus and method for efficient communication of producer/consumer buffer status.
2. Description of Related Art
In a data processing system, one processor or device typically acts as a producer by placing data into a shared buffer while another processor or device acts as a consumer by reading and processing the data placed there by the producer. For example, consider a data processing system where a producer and a consumer, independently operating on processors or devices within the data processing system, have access to a shared data buffer region. The shared data buffer region may be located, for example, in shared system or I/O memory and is commonly accessible by both parties. In addition to the shared buffer region, two state variables are shared between the producer and consumer: a head pointer (or index) and a tail pointer (or index), as shown in FIG. 1A.
FIG. 1A is an exemplary diagram of a shared buffer region in accordance with a prior art system. As shown in FIG. 1A, the shared buffer region 100 has an associated tail pointer 120 and head pointer 110. The head pointer 110 represents the next unused location in the shared buffer region 100. The tail pointer 120 represents the last unprocessed data location in the shared buffer region 100.
As a producer places data into the shared buffer region 100, the producer increments the head pointer 110. In this way, the producer indicates to consumers that new data is available for the consumers. Likewise, as the consumer retrieves data from the shared buffer region 100, the consumer increments the tail pointer 120, thereby indicating that data has been read from the shared buffer region 100. The amount of data available in the shared buffer region 100 is indicated by the difference between the head pointer 110 and tail pointer 120. This is referred to as the “active” data region 140 in the shared buffer region 100. The portion of the shared buffer region 100 that is behind the tail pointer 120 is referred to as the “inactive” (or old) data region 130. An empty shared buffer region is identified by setting the head pointer 110 and tail pointer 120 to the same location in the shared buffer region 100.
When there is no constraint on the size of the shared buffer region, i.e. when there is an infinite amount of storage space available for the shared buffer region 100, the head pointer 110 and tail pointer 120 may be incremented indefinitely. However, in most systems, it is more realistic to have only a fixed amount of storage space available for the shared buffer region 100. In this case, it is possible to reclaim the inactive region 130 by implementing what is known as a circular first-in-first-out (FIFO) type shared buffer region 100. This type of shared buffer region is illustrated in FIG. 1B.
As shown in FIG. 1B, the head pointer 110 and tail pointer 120 are incremented as described above with regard to FIG. 1A, however when the end of the shared buffer region 100 is encountered, the head and tail pointers 110 and 120 are permitted to wrap back to the beginning of the shared buffer region 100. As with the shared buffer region 100 shown in FIG. 1A, the active data region 140 is defined as the portion of the shared buffer region 100 between the head pointer 110 and tail pointer 120. However, with the FIFO shared buffer region, both the producer and consumer must now account for the situation where the head pointer 110 has wrapped beyond the end of the shared buffer region 100, i.e. back to the beginning of the shared buffer region 100, but the tail pointer 120 has not wrapped.
This requires efficient communication of the current values for the head and tail pointers 110 and 120 to both the producer and the consumer. The consumer is primarily concerned with monitoring updates to the head pointer 110 and the producer is primarily concerned with monitoring updates to the tail pointer 120. Before a consumer can begin processing, it must know that the head pointer 110 and tail pointer 120 point to different entries in the shared buffer region 100. Likewise, before the producer can add data to the shared buffer region 100, the producer must ensure that the amount of data to be added will not overflow the tail pointer 120.
A simple implementation may involve storing the state variables, i.e. the head pointer 110 and tail pointer 120, in shared system memory and monitoring these state variables remotely. FIG. 2A illustrates this exemplary implementation.
As shown in FIG. 2A a producer 250 performs updates to the head pointer 210 in shared memory 230 and monitors the current state of tail pointer 220 in shared memory 230 when writing data to the shared buffer region 240. Similarly, the consumer 260 updates the tail pointer 220 in shared memory 230 and monitors the current state of the head pointer 210 in shared memory 230 when reading data from the shared buffer region 240.
The producer 250 and consumer 260 each perform updates and monitoring of the head pointer 210 and tail pointer 220 in shared memory 230 remotely. That is, the head pointer 210 and tail pointer 220 are not located in a memory local to the producer 250 or the consumer 260. Thus, the producer 250 and consumer 260 must access these pointers 210 and 220 via a bus or other communication interface that is not local to the producer 250 or consumer 260. Typically, the producer 250 and consumer 260 poll the remote shared memory 230 in order to obtain information regarding the head and tail pointers 210 and 220. As a result, this updating and monitoring requires additional resources, e.g., processor cycles, bus bandwidth, etc., within the system to support these operations. Because of the need to utilized additional system resources, this solution may be considered too detrimental to overall system performance.
In an alternative approach, the head and tail pointers 210 and 220 are maintained in a memory or registers that are local to either the producer 250 or the consumer 260 in order to improve performance of that one party, i.e. the producer 250 or the consumer 260, to which the pointers 210 and 220 are made local. FIG. 2B illustrates such an alternative implementation in which the head pointer 210 and tail pointer 220 are stored in a local memory region 270 to one of the producer 250 and consumer 260 (in the depicted example, the local memory region 270 is local to the consumer 260).
As shown in FIG. 2B, the head pointer 210 and tail pointer 220 are stored in local memory region 270 that is local to consumer 260. This local memory region 270 is separate from shared memory 230 and shared buffer region 240. The producer 250 must remotely monitor, i.e. poll, the value of the tail pointer 220 in order to determine the amount of free space remaining in the shared buffer region 240. This may lead to serious degradation of performance for the producer, as the latency for reading remote locations can be several orders of magnitude worse than for main shared memory storage. Of course the situation could be reversed, requiring that the consumer 260 remotely monitor the head pointer 210 in a local memory region local to the producer 250, for example.